﻿Imports Microsoft.Win32 'Assists in Registry Reading & Writing

Public Class frmUninstall

    Private strUninstallStrings() As String 'Array to hold Uninstall commands for each program

    Private NewUninstallStrArr 'Filtered array containing ONLY valid uninstall commands

    Private Sub frmUninstall_Load(sender As Object, e As EventArgs) Handles Me.Load

        'Location in Registry where all uninstall "settings" are stored
        Dim ParentKey As RegistryKey = _
            Registry.LocalMachine.OpenSubKey("SOFTWARE\MICROSOFT\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products")

        Dim count As Integer = 0 'Loop Counter
        Dim ChildKey As RegistryKey 'Sub key of Parent key, to read necessary Uninstall properties

        'Loop through each GUID listed
        For Each child As String In ParentKey.GetSubKeyNames()

            ChildKey = ParentKey.OpenSubKey(child).OpenSubKey("InstallProperties") 'Read InstallProperties value(s)
            If Not ChildKey Is Nothing Then 'If not empty, display inside ListView

                Dim LItem As New ListViewItem() 'Create new ListView item

                LItem.Text = ChildKey.GetValue("DisplayName").ToString 'First Column ( Main Item ) Text - Display Name
                LItem.SubItems.Add(ChildKey.GetValue("Publisher").ToString) 'Publisher
                LItem.SubItems.Add(ChildKey.GetValue("InstallDate").ToString) 'Install Date
                LItem.SubItems.Add(ChildKey.GetValue("EstimatedSize").ToString) 'Estimated Size
                LItem.SubItems.Add(ChildKey.GetValue("DisplayVersion").ToString) 'Display Version
                LItem.SubItems.Add(ChildKey.GetValue("InstallLocation").ToString) 'Install Location

                ReDim Preserve strUninstallStrings(count) 'Redim Array

                If ChildKey.GetValue("UninstallString") IsNot Nothing Then 'Determine Uninstall Command(s)

                    strUninstallStrings(count) = ChildKey.GetValue("UninstallString") 'Store each command for each program
                    lvApps.Items.Add(LItem) 'Add ListItem

                Else 'If No Uninstall Command Present, Identify it

                    strUninstallStrings(count) = "No Uninstall String"

                End If

            End If

            count += 1 'Increment Counter for each item

            
        Next

        'Use LINQ to filter strUninstallStrings array, to only get valid programs with valid uninstall strings
        NewUninstallStrArr = (From str In strUninstallStrings
              Where Not {"No Uninstall String"}.Contains(str)).ToArray() 'New array to be used

    End Sub

    Private Sub lvApps_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lvApps.SelectedIndexChanged

        btnUninstall.Visible = True 'Upon itemn selection make these controls visible

    End Sub

    Private Sub btnUninstall_Click(sender As Object, e As EventArgs) Handles btnUninstall.Click

        'Use Shell to execute uninstall command
        Dim procID As Integer
        Dim strUninstall As String = NewUninstallStrArr(lvApps.FocusedItem.Index)


        procID = Shell(NewUninstallStrArr(lvApps.FocusedItem.Index), AppWinStyle.NormalFocus)

    End Sub
    Private Sub ColumnClick(ByVal o As Object, ByVal e As ColumnClickEventArgs) Handles lvApps.ColumnClick
        ' Set the ListViewItemSorter property to a new ListViewItemComparer  
        ' object. Setting this property immediately sorts the  
        ' ListView using the ListViewItemComparer object. 
        Me.lvApps.ListViewItemSorter = New ListViewItemComparer(e.Column)
    End Sub

End Class

' Implements the manual sorting of items by columns. 
Class ListViewItemComparer
    Implements IComparer

    Private col As Integer

    Public Sub New()
        col = 0
    End Sub

    Public Sub New(ByVal column As Integer)
        col = column
    End Sub

    Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
       Implements IComparer.Compare
        Return [String].Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)
    End Function
End Class

